package com.softwinner.awbt.fragment.finterface;

import android.text.TextUtils;

import java.util.HashMap;

/**
 * Created by xiasj on 18-1-3.
 */

public class FunctionManager {

    private static class LazyHolder {
        private static final FunctionManager INSTANCE = new FunctionManager();
    }


    private FunctionManager() {
        mFunctionNoParamNoResult = new HashMap<>();
        mFunctionWithParamWithResult = new HashMap<>();
        mFunctionWithParamNoResult = new HashMap<>();
        mFunctionNoParamWithResult = new HashMap<>();
    }

    public static FunctionManager getInstance() {
        return LazyHolder.INSTANCE;
    }

    /**
     * 添加无参数无返回值
     *
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionNoParamNoResult function) {
        if (mFunctionNoParamNoResult != null) {
            mFunctionNoParamNoResult.put(function.functionName, function);
        }
        return this;
    }

    /**
     * 添加无参数无返回值
     *
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionWithParamWithResult function) {
        if (mFunctionWithParamWithResult != null) {
            mFunctionWithParamWithResult.put(function.functionName, function);
        }
        return this;
    }

    /**
     * 添加无参数无返回值
     *
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionWithParamNoResult function) {
        if (mFunctionWithParamNoResult != null) {
            mFunctionWithParamNoResult.put(function.functionName, function);
        }
        return this;
    }

    /**
     * 添加无参数无返回值
     *
     * @param function
     * @return
     */
    public FunctionManager addFunction(FunctionNoParamWithResult function) {
        if (mFunctionNoParamWithResult != null) {
            mFunctionNoParamWithResult.put(function.functionName, function);
        }
        return this;
    }

    /**
     * 执行没参数没返回值的
     *
     * @param key
     */
    public void invokeFunction(String key) {
        if (TextUtils.isEmpty(key)) {
            return;
        }
        if (mFunctionNoParamNoResult != null) {
            FunctionNoParamNoResult functionNoParamNoResult = mFunctionNoParamNoResult.get(key);
            if (functionNoParamNoResult != null) {
                functionNoParamNoResult.function();
            } else {
                try {
                    throw new FunctionException("function not found");
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 有参数有返回值
     *
     * @param key
     * @param result
     * @param <Result>
     * @return
     */
    public <Result> Result invokeFunction(String key, Class<Result> result) {
        if (TextUtils.isEmpty(key)) {
            return null;
        }
        if (mFunctionNoParamWithResult != null) {
            FunctionNoParamWithResult f = mFunctionNoParamWithResult.get(key);
            if (f != null) {
                if (result == null) {
                    return (Result) f.function();
                } else {
                    return result.cast(f.function());
                }

            } else {
                try {
                    throw new FunctionException("function not found");
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 有参数有返回值
     *
     * @param key
     * @param param
     * @param <Param>
     * @return
     */
    public <Param> void invokeFunction(String key, Param param) {
        if (TextUtils.isEmpty(key)) {
            return;
        }
        if (mFunctionWithParamNoResult != null) {
            FunctionWithParamNoResult f = mFunctionWithParamNoResult.get(key);
            if (f != null) {
                f.function(param);

            } else {
                try {
                    throw new FunctionException("function not found");
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        }
        return;
    }

    /**
     * 有参数有返回值
     *
     * @param key
     * @param param
     * @param result
     * @param <Result>
     * @param <Param>
     * @return
     */
    public <Result, Param> Result invokeFunction(String key, Param param, Class<Result> result) {
        if (TextUtils.isEmpty(key)) {
            return null;
        }
        if (mFunctionWithParamWithResult != null) {
            FunctionWithParamWithResult f = mFunctionWithParamWithResult.get(key);
            if (f != null) {
                if (result == null) {
                    return (Result) f.function(param);
                } else {
                    return result.cast(f.function(param));
                }

            } else {
                try {
                    throw new FunctionException("function not found");
                } catch (FunctionException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }


    private static HashMap<String, FunctionNoParamNoResult> mFunctionNoParamNoResult;
    private static HashMap<String, FunctionWithParamWithResult> mFunctionWithParamWithResult;
    private static HashMap<String, FunctionWithParamNoResult> mFunctionWithParamNoResult;
    private static HashMap<String, FunctionNoParamWithResult> mFunctionNoParamWithResult;
}
